/*
 ______________________________________________________
/??????????????????????????????????????????????????????\
|          Default Engine                              |
|                                                      |
|   Feel free to copy, use and change this script as   |
|        long as this part remains unchanged.          |
|                                                      |
|      Visit my website at http://www.trucoder.com     |
|                                                      |
|                                                      |
|              Last Updated: May, 2007                 |
\______________________________________________________/
 ??????????????????????????????????????????????????????
*/

/**
 * This class needds to implement all the public methods of EngineInterface
 */
//Default Constructor
function EngineImpl (){

}
EngineImpl.inheritsFrom( Footbar.Engine );
EngineImpl.prototype.id="LocalEngine";
EngineImpl.prototype.init=function(){
    //Initalize superclass
    //Metadata
    var engineMetadata={
        loginRequired:true,
        title:'Local XML Database.',
        watchDogEnabled:false,
        synchonizationEnabled:false,
        description:'Snippets are stored localy in XML files.',
        www:'http://localhost',
        author:'Grzegorz Bugaj',
        version:'1.2'
    };
    this.parent.setMetadata.call(this, engineMetadata);
}

EngineImpl.prototype.retriveKeywordsXML=function(){
    var url="chrome://footbar/content/xml/keywords.xml"
    var httpRequest;
    httpRequest = new XMLHttpRequest();
    httpRequest.overrideMimeType('text/xml');
    httpRequest.open('GET', url, false);
    httpRequest.send(null);
    return httpRequest.responseXML;
}


EngineImpl.prototype.validateBeforeUpdate=function(data){
    //Same validation as for saving
    return this.validateBeforeSave(data);
}
/**
 * Update the snippet
 * @param {Object} data
 */
EngineImpl.prototype.updateSnippet=function(data){
    try {
        var xmlDoc=this.loadSourceXML();
        var root=xmlDoc.getElementsByTagName('root')[0];
        //Remove the found node from the root Node
        var iteratorRow = xmlDoc.evaluate( '/root/row[@uid="'+data.uid+'"]', xmlDoc, null, XPathResult.ANY_TYPE, null );
        var thisNode = iteratorRow.iterateNext();
        root.removeChild(thisNode);
        var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\source.xml";
        var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(xmlDoc, 0);
        Footbar.Util.writeFileData(filePath, output);
        this.saveSnippet(data)
    }
    catch (e) {
        alert( e );
    }
}
/**
 * Delete the snippet
 * @param {Object} data
 */
EngineImpl.prototype.deleteSnippet=function(data){
    try {
        var xmlDoc=this.loadSourceXML();
        var root=xmlDoc.getElementsByTagName('root')[0];
        //Remove the found node from the root Node
        var iteratorRow = xmlDoc.evaluate( '/root/row[@uid="'+data.uid+'"]', xmlDoc, null, XPathResult.ANY_TYPE, null );
        var thisNode = iteratorRow.iterateNext();
        root.removeChild(thisNode);
        var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\source.xml";
        var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(xmlDoc, 0);
        Footbar.Util.writeFileData(filePath, output);

        updateSearchDisplay();
    }
    catch (e) {
        alert( e );
    }
}



EngineImpl.prototype.saveSnippet=function(data){
    var xmlDoc=this.loadSourceXML();
    var root=xmlDoc.getElementsByTagName('root')[0];
    var row=document.createElement('row');
    var title=document.createElement('title');
    title.textContent=data.title;
    var keywords=document.createElement('keywords');

    var kwdata=data.keywords;
    var foundNewTag=false;
    var customKeywords=new String(data.customKeywords);
    customKeywords=customKeywords.split(",");
    for(var k=0;k<customKeywords.length;k++){
        //DontAllow blanks
        if(customKeywords[k].toLowerCase()=="" || customKeywords[k].toLowerCase()==" "){
            continue;
        }
        //Check if the keywords file already contains this tag
        var foundTag=false;
        var tagXML=this.loadKeywordsXML();
        var tagList=tagXML.getElementsByTagName('pair');
        for(var p=0;p<tagList.length;p++){
            var tag=tagList[p];
            if(tag.getAttribute("key").toLowerCase()==customKeywords[k].toLowerCase()){
                alert("TAG ALREADY EXISTS");
                foundTag=true;
                break;
            }
        }
        kwdata.push({
            key:customKeywords[k],
            label:customKeywords[k]
        });

        if(!foundTag){
            var tagRoot=tagXML.getElementsByTagName('root')[0];
            var pair=document.createElement('pair');
            var attValue=xmlDoc.createAttribute("value");
            attValue.value=customKeywords[k];
            pair.setAttributeNode(attValue);

            var attKey=xmlDoc.createAttribute("key");
            attKey.value=customKeywords[k];
            pair.setAttributeNode(attKey);
            tagRoot.appendChild(pair);
            foundNewTag=true;
        }
    }

    if(foundNewTag){
        var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\keywords.xml";
        var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(tagXML, 0);
        Footbar.Util.writeFileData(filePath, output);
    }

    for(var i=0;i<kwdata.length;i++){
        var pair=document.createElement('pair');
        var attValue=xmlDoc.createAttribute("value");
        attValue.value=kwdata[i].label;
        pair.setAttributeNode(attValue);

        var attKey=xmlDoc.createAttribute("key");
        attKey.value=kwdata[i].key;
        pair.setAttributeNode(attKey);
        keywords.appendChild(pair);
    }

    var description=document.createElement('description');
    description.textContent=data.description;

    var uniqueKey=xmlDoc.createAttribute("uid");
    //UniqueKey
    var ranNum;
    if(data.uid==null){
        ranNum= Math.floor(Math.random()*(new Date().getTime()));
    }else{
        ranNum=data.uid;
    }
    uniqueKey.value=ranNum;
    row.setAttributeNode(uniqueKey);


    var code=document.createElement('code');
    var cdata=document.createCDATASection(data.code);
    code.appendChild(cdata);

    var attLang=xmlDoc.createAttribute("language");
    attLang.value=data.language;
    code.setAttributeNode(attLang);

    row.appendChild(title);
    row.appendChild(keywords);
    row.appendChild(description);
    row.appendChild(code);

    root.appendChild(row);

    //writeout data to file
    var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\source.xml";
    var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(xmlDoc, 0);
    Footbar.Util.writeFileData(filePath, output);
    Footbar.Util.notifyMessage("Snippet saved");
}

EngineImpl.prototype.validateBeforeSave=function(snippet){
    var msg="";
    var isValid=true;
    if(snippet.title==null || snippet.title==""){
        msg+="Title is blank.\n";
        isValid=false;
    }
    if(snippet.keywords.length==0 && snippet.customKeywords==""){
        msg+="No tags specified.\n";
        isValid=false;
    }

    if(snippet.code==null || snippet.code==""){
        msg+="No Code Snippet specified.\n";
        isValid=false;
    }

    if(!isValid){
        var fmsg="Correct following before saving again:\n";
        fmsg+="--------------------------------------\n"
        fmsg+=msg;
        alert(fmsg);
    }
    return isValid;
}

/**
 * 
 * @param {Array} keywordsArray
 * @param {int} type 0=AND 1=OR
 */
EngineImpl.prototype.searchByKeywords=function(keywords, type){
    var outputXML=document.implementation.createDocument("ns","root",null);
    var outputRoot=outputXML.getElementsByTagName("root")[0];

    if(keywords.length==0){
        return outputXML;
    }
    var delim=" and ";
    if(parseInt(type)==0){
        delim=" and ";
    }else{
        delim=" or ";
    }

    var query="";
    var sQuery="";
    for(var i=0;i<keywords.length;i++){
        if(i==keywords.length-1){
            delim=" ";
        }
        sQuery+=' keywords/pair[@key="'+keywords[i]+'"]'+delim;
    }

    /// //root/row[keywords/pair[@key="SQL"] and keywords/pair[@key="Java"]]
    query='//root/row['+sQuery+']';

    var xmlDoc=this.loadSourceXML();
    var resultsetIterator = xmlDoc.evaluate( query, xmlDoc, null, XPathResult.ANY_TYPE, null );
    var resultset=resultsetIterator.iterateNext();
    while(resultset){
        outputRoot.appendChild(resultset.cloneNode(true));
        resultset=resultsetIterator.iterateNext();
    }

    return  outputXML;
}


EngineImpl.prototype.loadSourceXML=function(){
    var url="chrome://footbar/content/xml/source.xml"
    var httpRequest;
    httpRequest = new XMLHttpRequest();
    httpRequest.overrideMimeType('text/xml');
    httpRequest.open('GET', url, false);
    httpRequest.send(null);
    return httpRequest.responseXML;
}

EngineImpl.prototype.loadKeywordsXML=function(){
    var url="chrome://footbar/content/xml/keywords.xml"
    var httpRequest;
    httpRequest = new XMLHttpRequest();
    httpRequest.overrideMimeType('text/xml');
    httpRequest.open('GET', url, false);
    httpRequest.send(null);
    return httpRequest.responseXML;
}

EngineImpl.prototype.searchByText=function(text){
    var xmldata=this.loadSourceXML();
    var root = xmldata.getElementsByTagName("root")[0];
    var items = root.getElementsByTagName("row");
    var isCandidate=true;
    var nodesToRemove=[];
    for (var i=0;i<items.length;i++){
        var itemrow=items[i];
        var title=itemrow.getElementsByTagName("title")[0];
        var description=itemrow.getElementsByTagName("description")[0];
        title=new String(title.textContent);
        isCandidate=true;
        var keywords=text.split(" ");
        for(var j=0;j<keywords.length;j++){
            var word=title.match(new RegExp(keywords[j], "gi"));
            if(!word){
                isCandidate=false;
                break;
            }
        }
        if(!isCandidate){
            nodesToRemove.push(itemrow);
        }
    }
    var node=null;
    while((node=nodesToRemove.pop())!=null){
        root.removeChild(node);
    }
    return xmldata;//httpRequest.responseXML;
}
